import { User, Goldrecord } from '../modal/index'; // 数据库实体类
import { statusList, sequelizeStatus } from '../common/status'; // 数据库实体类
import crypto from 'crypto'; // 数据库实体类
import baseDao from '../lib/baseDao'; // 用于获取实例化的sequelize
import CONFIG from '../../config/config.config'
import { access_token } from '../common/token'; // 微信接口鉴权
import wechatApi from '../lib/wechatapi'; // 微信接口API


// permission
function checkPermission(Request, Response, minLevel) {
  return new Promise((resolve, reject) => {
    let token = Request.headers.token;
    if (token) {
      token = aesDecrypt(token)
    } else {
      Response.status(401).send({ message: statusList[401] });
      return;
    }
    if (token) {
      let uid = JSON.parse(token).uid
      let timeStamp = JSON.parse(token).timeStamp
      console.log(CONFIG.appNameC, '用户ID：', uid) // 输出用户路径，必须
      // 登陆过期判断
      // let restTime = new Date().valueOf() - timeStamp
      // if (restTime > 1000 * 60 * 60 * 24) {
      //   Response.status(401).send({ message: statusList[401] });
      // }
      //通过权限校验
      User.Modal.findAll({
        where: {
          id: uid
        },
        raw: true, // 返回标准json格式
        // attributes: { exclude: ['password', 'unionId', 'openId'] } // 过滤字段
      }).then(res => {
        if (res && res.length > 0) {
          let permissionFlag = res[0].level > minLevel;
          if (!permissionFlag) {
            Response.status(403).send({ message: statusList[403] });
          } else {
            //通过权限校验
            resolve(res[0])
          }
        } else {
          Response.status(300).send({ message: "抱歉，当前用户不存在" });
        }
      }).catch(err => {
        console.log(err)
        reject('err')
      });
    } else {
      Response.status(401).send({ message: statusList[401] });
    }
  })
}

async function reduceMoney(param, transaction, Response) {
  // 账户扣款
  return new Promise(async (resolve, reject) => {
    // 1元=10积分
    let finalGold = parseInt(Number(param.originGold) - Number(param.reduceGold))
    if (Number(finalGold) < 0) {
      await transaction.rollback() // 回滚
      Response.status(300).send({ message: "扣款出错，扣款后金额为负数" });
      // resolve(finalGold)
      return;
    }
    User.Modal.update({
      gold: finalGold
    }, {
        where: {
          id: param.userId,
        },
        transaction: transaction
      }).then(async res => {
        if (res && res.length > 0) {
          Goldrecord.Modal.create({
            userId: param.userId,
            title: param.title,
            originGold: param.originGold,
            finalGold: finalGold,
            change: `-${param.reduceGold}`,
          },
            { transaction: transaction },
          ).then(async res => {
            if (res && res.id) {
              resolve(finalGold)
            } else {
              await transaction.rollback() // 回滚
              Response.status(300).send({ message: "金额变动记录失败" });
            }
          }).catch(async err => {
            console.log(err)
            await transaction.rollback() // 回滚
            Response.status(500).send({ message: sequelizeStatus[err.name] || statusList[500] || err.name });
          });
        } else {
          await transaction.rollback() // 回滚
          Response.status(300).send({ message: "用户查询失败" });
        }
      }).catch(async err => {
        console.log(err)
        await transaction.rollback() // 回滚
        Response.status(500).send({ message: sequelizeStatus[err.name] || statusList[500] || err.name });
      });
  })
}

async function addMoney(param, transaction, Response) {
  // 加积分
  return new Promise(async (resolve, reject) => {
    // 1元=10积分
    User.Modal.findAll({
      where: {
        id: param.userId,
      },
      raw: true, // 返回标准json格式
    }).then(users => {
      param.originGold = users[0].gold
      let finalGold = parseInt(Number(param.originGold) + Number(param.addGold))
      User.Modal.update({
        gold: finalGold
      }, {
          where: {
            id: param.userId,
          },
          transaction: transaction
        }).then(async res => {
          if (res && res.length > 0) {
            Goldrecord.Modal.create({
              userId: param.userId,
              title: param.title,
              originGold: param.originGold,
              finalGold: finalGold,
              change: `+${param.addGold}`,
            },
              { transaction: transaction }
            ).then(async res => {
              if (res && res.id) {
                resolve(finalGold)
              } else {
                await transaction.rollback() // 回滚
                Response.status(300).send({ message: "金额变动记录失败" });
              }
            }).catch(async err => {
              console.log(err)
              await transaction.rollback() // 回滚
              Response.status(500).send({ message: sequelizeStatus[err.name] || statusList[500] || err.name });
            });
          } else {
            await transaction.rollback() // 回滚
            Response.status(300).send({ message: "用户查询失败" });
          }
        }).catch(async err => {
          console.log(err)
          await transaction.rollback() // 回滚
          Response.status(500).send({ message: sequelizeStatus[err.name] || statusList[500] || err.name });
        });
    }).catch(async err => {
      console.log(err)
      await transaction.rollback() // 回滚
      Response.status(500).send({ message: sequelizeStatus[err.name] || statusList[500] || err.name });
    });
  })
}

async function sendMuban(mubanParam, Response) { // 发送模板消息
  return new Promise(async (resolve, reject) => {
    await getAccessToken()
    let param = {
      form_id: mubanParam.formId,
      page: mubanParam.page, // 点击模板跳转页面
      access_token: access_token.token,
      touser: mubanParam.openId,
      template_id: mubanParam.templateId, // 模板消息ID
      data: mubanParam.data
    }
    wechatApi.sendMuban(param).then(async res => {
      // 不论成功与否都返回
      console.log(res)
      resolve(res)
    })
  })
}

async function sendDingyue(mubanParam, Response) { // 发送订阅消息
  return new Promise(async (resolve, reject) => {
    await getAccessToken()
    let param = {
      page: mubanParam.page, // 点击模板跳转页面
      access_token: access_token.token,
      touser: mubanParam.openId,
      template_id: mubanParam.templateId, // 模板消息ID
      data: mubanParam.data
    }
    wechatApi.sendDingyue(param).then(async res => {
      // 不论成功与否都返回
      console.log(res)
      resolve(res)
    })
  })
}

async function getAccessToken() {
  return new Promise((resolve, reject) => {
    if (access_token.expiredAt <= new Date().valueOf()) { // access过期
      wechatApi.getAccessToken({ grant_type: 'client_credential' }).then(res => {
        access_token.token = res.access_token
        access_token.expiredAt = new Date().valueOf() + 7200 * 1000
        resolve('success')
      })
    } else {
      resolve('success')
    }
  })
}

function aesEncrypt(data) {
  let key = CONFIG.tokenKey
  const cipher = crypto.createCipher('aes192', key);
  var crypted = cipher.update(data, 'utf8', 'hex');
  crypted += cipher.final('hex');
  return crypted;
}

function aesDecrypt(encrypted) {
  let key = CONFIG.tokenKey;
  const decipher = crypto.createDecipher('aes192', key);
  var decrypted = decipher.update(encrypted, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

function toJson(array, keys) {
  // array, keys 都传数组
  // 将数组内指定字段转换为josn
  array.forEach(arr => {
    keys.forEach(key => {
      arr[key] = JSON.parse(arr[key])
    });
  });
  return array;
}

function toString(array, keys) {
  // array, keys 都传数组
  // 将数组内指定字段转换为josn
  array.forEach(arr => {
    keys.forEach(key => {
      arr[key] = JSON.stringify(arr[key])
    });
  });
  return array;
}

function createOrderNumber() {
  // 创建唯一订单号
  let orderNumber = "";
  let nowStr = String(new Date().valueOf())
  orderNumber = nowStr.charAt(8) + nowStr.charAt(9) + nowStr.charAt(10) + nowStr
  return orderNumber;
}

export {
  checkPermission,
  reduceMoney,
  addMoney,
  sendMuban,
  sendDingyue,
  getAccessToken,
  aesEncrypt,
  aesDecrypt,
  toJson,
  toString,
  createOrderNumber,
}